In [1]:
ls *.csv
In [2]:
cat inventarioA.csv
In [3]:
cat inventarioB.csv
In [4]:
import csv
import functools
IN_FILE_A = "inventarioA.csv"
IN_FILE_B = "inventarioB.csv"
OUT_FILE = "inventarioTotal.csv"
BRAND = "MODELO"
STOCK = "STOCK"
In [5]:
def get_stock_value(stockA, stockB = "0"):
"""
Receives two stock values 'stockA' and 'stockB'. If no 'stockB'
is provided, it is set to '0' by default.
Validates that both 'stockA' and 'stockB' can be converted to
numeric values. Raises ValueError if one of the stock values
is not numeric or if it is an invalid amount.
Returns the addition of both stock values.
"""
if ((not stockA.isdigit()) or (int(stockA) < 0)):
raise ValueError("{} is not a valid stock value!".format(stockA))
if ((not stockB.isdigit()) or (int(stockB) < 0)):
raise ValueError("{} is not a valid stock value!".format(stockB))
return int(stockA) + int(stockB)
In [6]:
def count(row):
"""
Receives a dictionary representing an inventory row.
Returns a new dictionary with the BRAND value as
key and the STOCK value as the associated value.
"""
return {row[BRAND]: get_stock_value(row[STOCK])}
In [7]:
def read_next_row(reader):
"""
Receives a csv reader and tries to read a new csv row.
Returns the read row. If there are no more rows to read,
returns None.
"""
try:
return next(reader)
except StopIteration:
return None
In [8]:
def _merge(readerA, readerB, writerOut):
"""
Receives two csv readers 'readerA' and 'readerB'. Each reader corresponds
to an inventory file with the format: BRAND, STOCK. Products listed in
both input files MUST be ordered by BRAND.
Receives csv writer writerOut, which corresponds to the desired output
file.
Merges inventory files and creates one unified inventory list with the
format: BRAND, STOCK; which is written to the provided output file.
"""
rowA = read_next_row(readerA)
rowB = read_next_row(readerB)
writerOut.writeheader()
while(rowA and rowB):
if(rowA[BRAND] == rowB[BRAND]):
writerOut.writerow({BRAND: rowA[BRAND], STOCK: get_stock_value(rowA[STOCK],rowB[STOCK])})
rowA = read_next_row(readerA)
rowB = read_next_row(readerB)
elif (rowA[BRAND] < rowB[BRAND]):
writerOut.writerow({BRAND: rowA[BRAND], STOCK: get_stock_value(rowA[STOCK])})
rowA = read_next_row(readerA)
else:
writerOut.writerow({BRAND: rowB[BRAND], STOCK: get_stock_value(rowB[STOCK])})
rowB = read_next_row(readerB)
row = rowA if(rowA) else rowB
reader = readerA if(rowA) else readerB
while(row):
writerOut.writerow({BRAND: row[BRAND], STOCK: get_stock_value(row[STOCK])})
row = read_next_row(reader)
In [9]:
def merge_inventories(inputA, inputB, output, merge_function):
"""
Receives two csv inventory files 'inputA' and 'inputB',
with the format: BRAND, STOCK. Products listed in both
input files MUST be ordered by BRAND. Receives the output
file where the unified inventory list with the format:
BRAND, STOCK will be saved.
"""
with open(inputA) as csvA:
readerA = csv.DictReader(csvA)
with open(inputB) as csvB:
readerB = csv.DictReader(csvB)
with open(output, "w") as csvC:
writerOut = csv.DictWriter(csvC, [BRAND, STOCK])
merge_function(readerA, readerB, writerOut)
In [10]:
def main():
merge_inventories(IN_FILE_A, IN_FILE_B, OUT_FILE, _merge)
main()
In [11]:
ls *.csv
In [12]:
cat inventarioA.csv
In [13]:
cat inventarioB.csv
In [14]:
cat inventarioTotal.csv